<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 闭包概念 -->
    <!-- <script>
        function add(a,b){
            // 返回一个基本数据类型
            return a + b
        }

        // 将运算的结果5值拷贝给result
        let result = add(2,3)

        let a = 456

        // 这是一个闭包函数/函数闭包
        function fa1(){
            let a = 123
            return function fb1(){
                console.log(a);
            }
        }

        function fa2(){
            let a = 321
            return function fb2(){
                console.log(a);
            }
        }

        const fb1 = fa1()
        fb1()//123

        const fb2 = fa2()
        fb2()//321
    </script> -->

    <!-- 来个实例 -->
    <!-- <script>
        // 银行账户
        function account(name,money){
            // 存款
            return function(n){
                money += n
                console.log(name,"最新余额",money);
            }
        }

        /* 张三的闭包 */
        const saveFn1 = account("张三",1)
        saveFn1(5000)
        saveFn1(5000)

        /* 李四的闭包 */
        const saveFn2 = account("李四",1)
        saveFn2(15000)
        saveFn2(15000)
    </script> -->

    <!-- 闭包的典型应用场景：闭包内存储数据 返回该数据的操作API -->
    <!-- <script>
        // 银行账户
        function account(name,money){

            /* 操作账户的API */
            return {
                // 存钱
                save:function(n){
                    money += n
                },

                // 取钱
                withdraw:function(n){
                    money -= n
                    return n
                },

                // 查询余额
                query:function(){
                    return money
                }
            }
        }

        /* 张三的闭包 */
        const apis = account("张三",0)
        apis.save(100)
        apis.withdraw(50)
        console.log(apis.query());
        

        /* 李四的闭包 */
        const apis2 = account("李四",0)
        apis2.save(1000)
        apis2.withdraw(500)
        console.log(apis2.query());
    </script> -->

    <!-- 广义闭包：暂时没有释放的函数执行空间 -->
    <!-- <script>
        let a = 456

        /* 
        fn在没有释放之前 就是一个闭包（封闭的函数作用域） 
        我可以在闭包未释放之前 在闭包内存取私有数据
        */
        function fn(){
            // 闭包内数据不污染外界
            let a = 123

            function inner(){
                // 访问闭包内的数据
                console.log(a);//123
            }
            inner()
        }
        fn()
    </script> -->

    <!-- 释放闭包 -->
    <script>
      // 银行账户
      function account(name, money) {
        /* 操作账户的API */
        return {
          // 存钱
          save: function (n) {
            money += n;
          },

          // 取钱
          withdraw: function (n) {
            money -= n;
            return n;
          },

          // 查询余额
          query: function () {
            return money;
          },
        };
      }

      /* 张三的闭包 */
      let apis = account("张三", 0);
      apis.save(100);
      apis.withdraw(50);
      console.log(apis.query());

      // 释放闭包
      // apis指向null而不再指向闭包函数的返回值
      // 函数闭包的返回值无人引用
      // 垃圾回收器稍后就会将其回收=>闭包得以释放=>避免了内存泄露
      apis = null;
    </script>
  </body>
</html>
